package com.ikingtech.framework.sdk.approve.callback.caller;

import com.ikingtech.framework.sdk.approve.callback.ApproveCallbackParam;
import com.ikingtech.framework.sdk.approve.callback.ApproveCallbackResolver;
import com.ikingtech.framework.sdk.context.security.Identity;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.core.support.LogHelper;
import com.ikingtech.framework.sdk.enums.common.FrameworkServerFeedbackTypeEnum;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.support.server.FrameworkServerFeedbackCaller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Set;

import static com.ikingtech.framework.sdk.cache.constants.CacheConstants.APPROVE_PROCESS_CALLBACK;
import static com.ikingtech.framework.sdk.context.constant.SecurityConstants.*;

/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
public class ApproveCallbackFeedbackCaller implements FrameworkServerFeedbackCaller {

    private final StringRedisTemplate redisTemplate;

    private final LoadBalancerClient loadBalancerClient;

    private final ApproveCallbackResolver resolver;

    @Override
    public R<Object> call(Object data) {
        ApproveCallbackParam param = (ApproveCallbackParam) data;
        Set<String> bizServerNames = this.redisTemplate.opsForSet().members(APPROVE_PROCESS_CALLBACK);
        if (Tools.Coll.isNotBlank(bizServerNames)) {
            for (String bizServerName : bizServerNames) {
                if ("server".equals(bizServerName)) {
                    this.resolver.resolve(param);
                    continue;
                }
                ServiceInstance client = this.loadBalancerClient.choose(bizServerName);
                if (null != client) {
                    try {
                        Tools.Http.post(Tools.Http.SCHEMA_HTTP + client.getHost() + ":" + client.getPort() + "/approve/callback/resolve",
                                Tools.Json.toJsonStr(param),
                                Tools.Coll.newMap(
                                        Tools.Coll.Kv.of(HEADER_INNER_IDENTITY, Identity.inner()),
                                        Tools.Coll.Kv.of(HEADER_CALLER, "INNER"),
                                        Tools.Coll.Kv.of(HEADER_TENANT_CODE, Me.tenantCode())
                                ));
                        LogHelper.info("APPROVE CALLBACK FEEDBACK", "审批回调执行完成[{}({})][param = {}]", bizServerName, client.getHost() + ":" + client.getPort(), data);
                    } catch (Exception e) {
                        LogHelper.info("APPROVE CALLBACK FEEDBACK", "审批回调执行异常[{}({})][param = {}][exception = {}]", bizServerName, client.getHost() + ":" + client.getPort(), data, e.getMessage());
                    }
                }
            }
        }
        return R.ok();
    }

    @Override
    public FrameworkServerFeedbackTypeEnum type() {
        return FrameworkServerFeedbackTypeEnum.APPROVE_PROCESS_CALLBACK_FEEDBACK;
    }
}
